<template>
  <div class="image-qa-container">
    <el-card class="image-qa-card">
      <div class="card-header">
        <h3>图像上传与问答</h3>
      </div>
      
      <!-- 按钮操作区 -->
      <div v-if="imageUrl || answerResult || chatHistory.length > 0" class="control-buttons">
        <el-button 
          type="danger" 
          size="small" 
          @click="clearHistory">
          清空记录
        </el-button>
      </div>
      
      <!-- 图片上传区域 -->
      <div class="upload-section">
        <el-upload
          class="image-uploader"
          :show-file-list="false"
          action="#"
          :auto-upload="false"
          :on-change="handleImageChange"
          accept="image/jpeg,image/png,image/gif,image/bmp"
        >
          <img v-if="imageUrl" :src="imageUrl" class="preview-image" />
          <div v-else class="upload-placeholder">
            <el-icon><Plus /></el-icon>
            <div class="upload-text">点击上传图片</div>
          </div>
        </el-upload>
        <div class="upload-tips">支持jpg、png、gif、bmp格式，大小不超过10MB</div>
      </div>

      <!-- OCR识别结果区域 -->
      <div v-if="ocrResult" class="ocr-section">
        <div class="section-title">OCR识别结果：</div>
        <el-card class="ocr-result-card">
          <pre class="ocr-text">{{ ocrResult }}</pre>
        </el-card>
      </div>

      <!-- 问题输入区域 -->
      <div class="question-section">
        <div class="section-title">请输入你的问题：</div>
        <el-input
          v-model="question"
          type="textarea"
          :rows="2"
          placeholder="请输入关于图片内容的问题..."
          :disabled="!imageFile"
        ></el-input>
      </div>

      <!-- 操作按钮区域 -->
      <div class="action-section">
        <el-button 
          type="primary" 
          @click="handleRecognize" 
          :disabled="!imageFile" 
          :loading="recognizing"
        >
          OCR识别
        </el-button>
        <el-button 
          type="success" 
          @click="handleAskQuestion" 
          :disabled="!imageFile || !question.trim()" 
          :loading="answering"
        >
          提问
        </el-button>
      </div>

      <!-- 问答结果区域 -->
      <div v-if="answerResult" class="answer-section">
        <div class="section-title">问题解答：</div>
        <el-card class="answer-result-card">
          <div class="answer-text" v-html="formatMessage(answerResult)"></div>
        </el-card>
      </div>
    </el-card>
  </div>
</template>

<script>
import { Plus } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import axios from 'axios'

export default {
  name: 'ImageQaCard',
  components: {
    Plus
  },
  data() {
    return {
      imageFile: null,
      imageUrl: '',
      ocrResult: '',
      question: '',
      answerResult: '',
      recognizing: false,
      answering: false,
      chatHistory: []
    }
  },
  methods: {
    // 处理图片变化
    handleImageChange(file) {
      this.imageFile = file.raw
      this.imageUrl = URL.createObjectURL(file.raw)
      this.ocrResult = ''
      this.answerResult = ''
      this.chatHistory = [] // 清空聊天历史
    },

    // 处理OCR识别
    async handleRecognize() {
      if (!this.imageFile) {
        ElMessage.warning('请先上传图片')
        return
      }

      this.recognizing = true
      try {
        const formData = new FormData()
        formData.append('file', this.imageFile)

        console.log('发送OCR请求:', '/api/ocr/recognize')
        
        // 直接使用axios发送请求，不经过api封装
        const response = await axios.post('/api/ocr/recognize', formData, {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        })
        
        console.log('OCR响应:', response)
        
        if (response.data && response.data.code === 200) {
          this.ocrResult = response.data.data
          // 将OCR识别结果填充到问题输入框
          this.question = this.ocrResult
          ElMessage.success('OCR识别成功，结果已填充到输入框')
        } else {
          throw new Error(response.data?.msg || '请求成功但返回异常')
        }
      } catch (error) {
        console.error('OCR识别失败详情:', error)
        if (error.response) {
          console.error('错误状态:', error.response.status)
          console.error('错误数据:', error.response.data)
        }
        ElMessage.error(error.response?.data?.msg || error.message || 'OCR识别失败')
      } finally {
        this.recognizing = false
      }
    },

    // 处理问题提问
    async handleAskQuestion() {
      if (!this.imageFile) {
        ElMessage.warning('请先上传图片')
        return
      }

      if (!this.question.trim()) {
        ElMessage.warning('请输入问题')
        return
      }

      this.answering = true
      try {
        console.log('发送问答请求:', '/api/chat')
        
        // 添加用户问题到聊天历史
        const userMessage = {
          role: 'user',
          content: this.question.trim()
        }
        this.chatHistory.push(userMessage)
        
        // 构建请求体，包含历史消息
        const chatRequest = {
          prompt: this.question.trim(),
          messages: this.chatHistory.map(msg => ({
            role: msg.role === 'user' ? 'user' : 'assistant', 
            content: msg.content
          })),
          useContext: true
        }
        
        // 使用axios直接发送JSON请求
        const response = await axios.post('/api/chat', chatRequest, {
          headers: {
            'Content-Type': 'application/json'
          },
          responseType: 'text' // 使用text类型接收流式响应
        })
        
        console.log('问答响应:', response)
        
        if (response.data) {
          this.answerResult = response.data
          // 添加AI回复到聊天历史
          this.chatHistory.push({
            role: 'assistant',
            content: response.data
          })
          ElMessage.success('问题回答成功')
        } else {
          throw new Error('回答数据为空')
        }
      } catch (error) {
        console.error('问答失败:', error)
        if (error.response) {
          console.error('错误状态:', error.response.status)
          console.error('错误数据:', error.response.data)
        }
        ElMessage.error(error.message || '问答失败')
      } finally {
        this.answering = false
      }
    },
    
    // 格式化消息文本
    formatMessage(text) {
      if (!text) return '';
      
      // 处理Markdown格式
      let formatted = text
        // 代码块
        .replace(/```([\s\S]*?)```/g, '<pre class="code-block">$1</pre>')
        // 行内代码
        .replace(/`([^`]+)`/g, '<code>$1</code>')
        // 粗体
        .replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>')
        .replace(/__([^_]+)__/g, '<strong>$1</strong>')
        // 斜体
        .replace(/\*([^*]+)\*/g, '<em>$1</em>')
        .replace(/_([^_]+)_/g, '<em>$1</em>')
        // 标题
        .replace(/^# (.+)$/gm, '<h1>$1</h1>')
        .replace(/^## (.+)$/gm, '<h2>$1</h2>')
        .replace(/^### (.+)$/gm, '<h3>$1</h3>')
        // 列表
        .replace(/^- (.+)$/gm, '<li>$1</li>')
        .replace(/^\d+\. (.+)$/gm, '<li>$1</li>')
        // 引用
        .replace(/^> (.+)$/gm, '<blockquote>$1</blockquote>')
        // 链接
        .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank">$1</a>')
        // 换行
        .replace(/\n/g, '<br>');
      
      return formatted;
    },

    // 清空历史记录
    clearHistory() {
      this.imageFile = null
      this.imageUrl = ''
      this.ocrResult = ''
      this.question = ''
      this.answerResult = ''
      this.chatHistory = []
      ElMessage.success('历史记录已清空')
    }
  }
}
</script>

<style scoped>
.image-qa-container {
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  padding: 0 16px;
}

@media (max-width: 768px) {
  .image-qa-container {
    padding: 0 8px;
  }
}

.image-qa-card {
  width: 100%;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
  border: none;
  background-color: #ffffff;
  padding: 16px;
}

@media (max-width: 768px) {
  .image-qa-card {
    padding: 12px 8px;
    border-radius: 8px;
  }
}

.card-header {
  margin-bottom: 24px;
  text-align: center;
  color: #303133;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
}

@media (max-width: 768px) {
  .card-header {
    margin-bottom: 16px;
    flex-direction: column;
    gap: 10px;
  }
}

.card-header h3 {
  font-size: 24px;
  font-weight: 600;
  margin: 0;
  color: #333;
}

@media (max-width: 768px) {
  .card-header h3 {
    font-size: 20px;
  }
}

.control-buttons {
  margin-bottom: 24px;
  text-align: right;
}

@media (max-width: 768px) {
  .control-buttons {
    text-align: center;
  }
}

.upload-section {
  margin-bottom: 32px;
}

.image-uploader {
  border: 2px dashed #e0e0e0;
  border-radius: 12px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  width: 100%;
  aspect-ratio: 16/9;
  max-height: 240px;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: all 0.3s ease;
  background-color: #fafafa;
}

@media (max-width: 768px) {
  .image-uploader {
    aspect-ratio: 4/3;
    border-radius: 8px;
  }
}

.image-uploader:hover {
  border-color: #409EFF;
  background-color: #f5f9ff;
}

.upload-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #909399;
}

.upload-placeholder :deep(.el-icon) {
  font-size: 32px;
  color: #c0c4cc;
  margin-bottom: 12px;
  background-color: #f0f2f5;
  padding: 16px;
  border-radius: 50%;
}

.upload-text {
  margin-top: 16px;
  font-size: 16px;
  color: #606266;
  font-weight: 500;
}

.preview-image {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.upload-tips {
  font-size: 13px;
  color: #909399;
  margin-top: 8px;
  text-align: center;
}

.section-title {
  font-weight: 600;
  margin-bottom: 16px;
  color: #303133;
  font-size: 18px;
}

@media (max-width: 768px) {
  .section-title {
    font-size: 16px;
    margin-bottom: 12px;
  }
}

.ocr-section, .question-section, .action-section, .answer-section {
  margin-bottom: 32px;
}

@media (max-width: 768px) {
  .ocr-section, .question-section, .action-section, .answer-section {
    margin-bottom: 24px;
  }
}

.ocr-result-card, .answer-result-card {
  margin-top: 16px;
  background-color: #f9f9fc;
  border-radius: 10px;
  border: none;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
}

@media (max-width: 768px) {
  .ocr-result-card, .answer-result-card {
    border-radius: 8px;
    margin-top: 12px;
  }
}

.ocr-text {
  white-space: pre-wrap;
  word-break: break-all;
  font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
  font-size: 15px;
  padding: 16px;
  line-height: 1.6;
  color: #444;
  border-radius: 8px;
  max-height: 300px;
  overflow-y: auto;
}

@media (max-width: 768px) {
  .ocr-text {
    font-size: 14px;
    padding: 12px;
    max-height: 250px;
  }
}

.answer-text {
  padding: 16px;
  line-height: 1.6;
  color: #444;
  font-size: 15px;
  max-height: 300px;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

@media (max-width: 768px) {
  .answer-text {
    font-size: 14px;
    padding: 12px;
    max-height: 250px;
  }
}

.answer-text :deep(pre.code-block) {
  background-color: #f5f5f5;
  padding: 12px;
  border-radius: 4px;
  margin: 8px 0;
  overflow-x: auto;
  font-family: 'SFMono-Regular', Consolas, monospace;
}

.answer-text :deep(code) {
  background-color: #f0f0f0;
  padding: 2px 4px;
  border-radius: 3px;
  font-family: 'SFMono-Regular', Consolas, monospace;
}

.answer-text :deep(blockquote) {
  border-left: 4px solid #ddd;
  padding-left: 16px;
  margin: 8px 0;
  color: #666;
}

.answer-text :deep(h1) {
  font-size: 24px;
  margin: 16px 0 8px 0;
  font-weight: 600;
}

.answer-text :deep(h2) {
  font-size: 20px;
  margin: 14px 0 8px 0;
  font-weight: 600;
}

.answer-text :deep(h3) {
  font-size: 18px;
  margin: 12px 0 8px 0;
  font-weight: 600;
}

.answer-text :deep(li) {
  margin: 4px 0 4px 20px;
  display: list-item;
  list-style: initial;
}

.action-section {
  display: flex;
  justify-content: center;
  gap: 24px;
  margin-top: 32px;
}

@media (max-width: 480px) {
  .action-section {
    flex-direction: column;
    gap: 16px;
    align-items: stretch;
  }
}

.action-section .el-button {
  padding: 12px 24px;
  font-size: 16px;
  font-weight: 500;
  border-radius: 8px;
  transition: all 0.3s;
  height: 48px;
  min-width: 120px;
}

@media (max-width: 480px) {
  .action-section .el-button {
    width: 100%;
    min-width: auto;
  }
}

.question-section .el-textarea :deep(.el-textarea__inner) {
  border-radius: 8px;
  padding: 12px 16px;
  border-color: #dcdfe6;
  transition: all 0.3s;
  resize: none;
  font-size: 15px;
}

.question-section .el-textarea :deep(.el-textarea__inner:focus) {
  border-color: #409eff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}
</style> 